home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / mtools.lha / mtools-2.0.7 / dir_write.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  4KB  |  179 lines

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <ctype.h>
  4. #include "msdos.h"
  5.  
  6. extern int fd, dir_dirty, clus_size, dir_entries;
  7. extern long dir_chain[MAX_DIR_SECS];
  8. extern unsigned char *dir_buf;
  9.  
  10. /*
  11.  * Write a directory entry.  A simple cache is used instead of something
  12.  * more elaborate.
  13.  */
  14.  
  15. void
  16. dir_write(num, dir)
  17. int num;
  18. struct directory *dir;
  19. {
  20.     unsigned char *offset;
  21.     char *memcpy();
  22.  
  23.     offset = dir_buf + (num * MDIR_SIZE);
  24.     memcpy((char *) offset, (char *) dir, MDIR_SIZE);
  25.     dir_dirty = 1;
  26.     return;
  27. }
  28.  
  29. /*
  30.  * Write a partially filled directory buffer to disk.  Resets dir_dirty to
  31.  * zero.
  32.  */
  33.  
  34. void
  35. dir_flush()
  36. {
  37.     int i, length;
  38.     unsigned char *offset;
  39.     void disk_write();
  40.  
  41.     if (fd < 0 || !dir_dirty)
  42.         return;
  43.  
  44.     length = dir_entries / 16;
  45.     for (i = 0; i < length; i++) {
  46.         offset = dir_buf + (i * MSECTOR_SIZE);
  47.         disk_write(dir_chain[i], offset, MSECTOR_SIZE);
  48.     }
  49.     dir_dirty = 0;
  50.     return;
  51. }
  52.  
  53. /*
  54.  * Convert a Unix filename to a legal MSDOS name.  Returns a pointer to
  55.  * a static area.  Will truncate file and extension names, will
  56.  * substitute the letter 'X' for any illegal character in the name.
  57.  */
  58.  
  59. unsigned char *
  60. dos_name(filename, verbose)
  61. char *filename;
  62. int verbose;
  63. {
  64.     static char *dev[9] = {"CON", "AUX", "COM1", "COM2", "PRN", "LPT1",
  65.     "LPT2", "LPT3", "NUL"};
  66.     char *s, buf[MAX_PATH], *name, *ext, *strcpy(), *strpbrk(), *strrchr();
  67.     static unsigned char ans[13];
  68.     int dot, modified, len;
  69.     register int i;
  70.  
  71.     strcpy(buf, filename);
  72.     name = buf;
  73.                     /* skip drive letter */
  74.     if (buf[0] && buf[1] == ':')
  75.         name = &buf[2];
  76.                     /* zap the leading path */
  77.     if (s = strrchr(name, '/'))
  78.         name = s + 1;
  79.     if (s = strrchr(name, '\\'))
  80.         name = s + 1;
  81.  
  82.     ext = "";
  83.     dot = 0;
  84.     len = strlen(name);
  85.     for (i = 0; i < len; i++) {
  86.         s = name + len -i -1;
  87.         if (*s == '.' && !dot) {
  88.             dot = 1;
  89.             *s = '\0';
  90.             ext = s +1;
  91.         }
  92.         if (islower(*s))
  93.             *s = toupper(*s);
  94.     }
  95.     if (*name == '\0') {
  96.         name = "X";
  97.         if (verbose)
  98.             printf("\"%s\" Null name component, using \"%s.%s\"\n", filename, name, ext);
  99.     }
  100.     for (i = 0; i < 9; i++) {
  101.         if (!strcmp(name, dev[i])) {
  102.             *name = 'X';
  103.             if (verbose)
  104.                 printf("\"%s\" Is a device name, using \"%s.%s\"\n", filename, name, ext);
  105.         }
  106.     }
  107.     if (strlen(name) > 8) {
  108.         *(name + 8) = '\0';
  109.         if (verbose)
  110.             printf("\"%s\" Name too long, using, \"%s.%s\"\n", filename, name, ext);
  111.     }
  112.     if (strlen(ext) > 3) {
  113.         *(ext + 3) = '\0';
  114.         if (verbose)
  115.             printf("\"%s\" Extension too long, using \"%s.%s\"\n", filename, name, ext);
  116.     }
  117.     modified = 0;
  118.     while (s = strpbrk(name, "^+=/[]:',?*\\<>|\". ")) {
  119.         modified++;
  120.         *s = 'X';
  121.     }
  122.     while (s = strpbrk(ext, "^+=/[]:',?*\\<>|\". ")) {
  123.         modified++;
  124.         *s = 'X';
  125.     }
  126.     if (modified && verbose)
  127.         printf("\"%s\" Contains illegal character(s), using \"%s.%s\"\n", filename, name, ext);
  128.  
  129.     sprintf((char *) ans, "%-8.8s%-3.3s", name, ext);
  130.     return(ans);
  131. }
  132.  
  133. /*
  134.  * Make a directory entry.  Builds a directory entry based on the
  135.  * name, attribute, starting cluster number, and size.  Returns a pointer
  136.  * to a static directory structure.
  137.  */
  138.  
  139. struct directory *
  140. mk_entry(filename, attr, fat, size, date)
  141. unsigned char *filename;
  142. unsigned char attr;
  143. unsigned int fat;
  144. long size, date;
  145. {
  146.     int i;
  147.     char *strncpy();
  148.     static struct directory ndir;
  149.     struct tm *now, *localtime();
  150.     unsigned char hour, min_hi, min_low, sec;
  151.     unsigned char year, month_hi, month_low, day;
  152.  
  153.     now = localtime(&date);
  154.     strncpy((char *) ndir.name, (char *) filename, 8);
  155.     strncpy((char *) ndir.ext, (char *) filename + 8, 3);
  156.     ndir.attr = attr;
  157.     for (i = 0; i < 10; i++)
  158.         ndir.reserved[i] = '\0';
  159.     hour = now->tm_hour << 3;
  160.     min_hi = now->tm_min >> 3;
  161.     min_low = now->tm_min << 5;
  162.     sec = now->tm_sec / 2;
  163.     ndir.time[1] = hour + min_hi;
  164.     ndir.time[0] = min_low + sec;
  165.     year = (now->tm_year - 80) << 1;
  166.     month_hi = (now->tm_mon + 1) >> 3;
  167.     month_low = (now->tm_mon + 1) << 5;
  168.     day = now->tm_mday;
  169.     ndir.date[1] = year + month_hi;
  170.     ndir.date[0] = month_low + day;
  171.     ndir.start[1] = fat / 0x100;
  172.     ndir.start[0] = fat % 0x100;
  173.     ndir.size[3] = size / 0x1000000L;
  174.     ndir.size[2] = (size % 0x1000000L) / 0x10000L;
  175.     ndir.size[1] = ((size % 0x1000000L) % 0x10000L) / 0x100;
  176.     ndir.size[0] = ((size % 0x1000000L) % 0x10000L) % 0x100;
  177.     return(&ndir);
  178. }
  179.